<template>
  <div class="TD-map">
    <div
      v-loading="loading"
      element-loading-background="rgba(0, 0, 0, 0.8)"
      :id="idName"
      class="TD-mapCanvas"
      @click="mouseClick"
      @mousemove="mouseMove"
    >
      <div class="TD-pre" v-if="codes.length>1" @click="handlePre">返回上一级</div>
    </div>
    <markBox />
  </div>
</template>

<script>
import * as THREE from "three";
import { getMapData } from "@/api/data";
import * as map from "@/utils/map";
import { createBg } from "@/utils/mesh/bgMesh";
import { createMap } from "@/utils/mesh/mapMesh";
import { createMarkBox, createTooltip } from "@/utils/mesh/LabelMesh";
import { colors, linewidth } from "@/utils/config";
import markBox from "@/components/map/components/markBox.vue";
import * as material from "@/utils/material";
export default {
  name: "three-map",
  components: {
    markBox
  },
  props: {
    // 标记点
    points: {
      type: Array,
      default: () => {}
    },
    // 光柱
    lights: {
      type: Array,
      default: () => {}
    },
    // 柱状图
    bars: {
      type: Array,
      default: () => {}
    },
    // 显示的地图的code
    code: {
      type: [String, Number],
      default: "100000"
    }
  },
  data() {
    return {
      idName: new Date().getTime() + "",
      codes: [this.code],
      form: {
        linewidth: linewidth,
        isBar: false,
        isLight: false
      },
      colors: colors,
      loading: false,
      scene: null, // 场景
      map: null,
      camera: null, // 相机
      outlinePass: null,
      renderer: null, // 渲染器
      controls: null, // 控制器
      size: null
    };
  },
  mounted() {
    this.init();
  },

  watch: {
    points: {
      immediate: true,
      deep: true,
      handler(newValue) {
        if (newValue && this.size && this.map) {
          this.addPoint();
        }
      }
    },
    lights: {
      immediate: true,
      deep: true,
      handler(newValue) {
        if (newValue && this.size && this.map) {
          this.addLight();
        }
      }
    },
    bars: {
      immediate: true,
      deep: true,
      handler(newValue) {
        if (newValue && this.size && this.map) {
          this.addBar();
        }
      }
    }
  },
  methods: {
    init() {
      const {
        renderer,
        scene,
        camera,
        outlinePass,
        controls
      } = map.createScene(this.idName);
      this.renderer = renderer;
      this.scene = scene;
      this.camera = camera;
      this.outlinePass = outlinePass;
      this.controls = controls;
      this.add();
    },
    handlePre() {
      this.codes.pop();
      this.add();
    },

    addPoint() {
      map.pointEvent(this.map, this.points, this.size, "Icon");
    },
    addLight() {
      map.pointEvent(this.map, this.lights, this.size, "lightPoint");
    },
    addBar() {
      map.pointEvent(this.map, this.bars, this.size, "bar");
    },

    addOthers() {
      // 添加标签
      map.allPointEvent(true, this.map, this.size, "label");
      // // 添加图标
      // this.toggle(false, "Icon");
      // 添加标记点
      this.addPoint();
      // 添加光柱
      this.addLight();
      // 添加柱状图
      this.addBar();
    },

    // 改变背景颜色
    changeBgColor(color) {
      this.renderer.setClearColor(color, 1); // 设置背景颜色和透明度
    },
    // 改变颜色
    changeColor(color, name, index) {
      material.setMaterialColor(this.colors); // 更新材质中的颜色
      this.scene.traverse(item => {
        if (item.colorName == name) {
          if (Array.isArray(item.material)) {
            item.material[index].color.set(color);
          } else {
            item.material.color.set(color);
          }
        }
      });
    },
    // 更改线条宽度
    changeLine(linewidth) {
      material.setMaterialLine(linewidth);
      this.scene.traverse(item => {
        if (item.name == "mapLine") {
          item.material.linewidth = linewidth;
        }
      });
    },

    add() {
      // 复位
      this.controls.reset();
      // 获取地图json数据
      this.loading = true;
      getMapData(this.codes[this.codes.length - 1])
        .then(data => {
          // 移除地图
          this.remove();
          // 建立地图3D模型
          this.map = createMap(data);
          // 添加背景
          const { size, center } = map.box3(this.map);
          this.size = size;
          const bgGroup = createBg(size, center);
          const group = new THREE.Group();
          group.name = "mapGroup";
          group.add(this.map, bgGroup);
          map.setCenter(this.map); // 设置中心点
          map.setScale(group, size); // 根据地图当前尺寸重置地图高度
          this.addOthers(); // 添加地图上的其他模型
          this.scene.add(group);
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    },

    // 移除场景上的所有模型
    remove() {
      map.removeMesh(this.scene, item => item.isGroup);
      // 去除地图上的标签
      document.getElementById(this.idName + "label").innerHTML = "";
    },

    // 点击事件
    mouseClick() {
      const intersects = map.getIntersects(
        this.idName,
        this.scene,
        this.camera
      );
      // 对点击的对象进行处理
      if (intersects.length > 0) {
        let intersect = intersects[0]?.object?.parent;
        // 1. 点击标记点
        if (intersects[0].object.name == "mark") {
          // 去除已有弹框
          map.removeMesh(this.map, item => item.name == "markBox");
          const self = intersects[0].object.self;
          // 添加新弹框
          const newMarkBox = createMarkBox("markBox", self, this.size);
          this.map.add(newMarkBox);
          return;
        }

        // 2. 点击柱状图
        if (intersects[0].object.name == "bar") {
          // 去除已有弹框
          map.removeMesh(this.map, item => item.name == "tooltip");
          const self = intersects[0].object.parent.self;
          // 添加新弹框
          const tooltip = createTooltip(self, this.size);
          this.map.add(tooltip);
          return;
        }
        // 3. 点击地图块
        // 到县级禁止下探 province/city/district
        // if (intersect?.self?.level == "district") return;
        if (intersect?.self?.adcode) {
          this.codes.push(intersect.self.adcode);
          this.add();
        }
      } else {
        // 点击其他部分，去除弹框
        map.removeMesh(
          this.map,
          item => item.name == "markBox" || item.name == "tooltip"
        );
      }
    },
    mouseMove() {
      let intersect = null;
      const intersects = map.getIntersects(
        this.idName,
        this.scene,
        this.camera
      );
    }
    // 获取点击模型
  }
};
</script>

<style lang="scss" scoped>
.TD-map {
  width: 100%;
  height: 100%;
}
.TD-mapCanvas {
  width: 100%;
  height: 100%;
  position: relative;
  .TD-pre {
    position: absolute;
    bottom: 10px;
    cursor: pointer;
    width: 124px;
    box-sizing: border-box;
    left: 50%;
    transform: translateX(-62px);
    font-size: 14px;
    padding: 5px 26px;
    border: 1px solid #006a97;
    color: #006a97;
  }
}
</style>